﻿using System;
using System.Collections.Generic;
using System.Linq;
using TradeHelp.MaterializedObjectViews.Views.Caches;
using TradeHelp.Utilities;

namespace TradeHelp.MaterializedObjectViews.Views
{
//    public class JoinView<TOuter, TInner, TResult, TKey> : QueryView<TResult>
//    {
//        private readonly IViewStream<TOuter> _outerProvider;
//        private readonly IViewStream<TInner> _innerProvider;
//        private readonly Func<TOuter, TKey> _outerKey;
//        private readonly Func<TInner, TKey> _innerKey;
//        private readonly Func<TOuter, TInner, TResult> _selector;
//        private readonly IViewCache<TResult> _cache;
//        private volatile bool _disposed;
//        private int _cacheVersion;
//        private StreamMessageDelegate<TResult> _callbacks;
//        private readonly IViewCache<TInner> _innerCache;
//        private readonly MsgSequencer<TInner> _innerCacheSequencer = new MsgSequencer<TInner>();
//
//        public JoinView(IViewStream<TOuter> outerProvider, Func<TOuter, TKey> outerKey, IViewStream<TInner> innerProvider, Func<TInner, TKey> innerKey, Func<TOuter, TInner, TResult> selector)
//        {
//            Invariant.CheckIsNull(outerProvider, "outerProvider");
//            Invariant.CheckIsNull(outerKey, "outerKey");
//            Invariant.CheckIsNull(innerProvider, "innerProvider");
//            Invariant.CheckIsNull(innerKey, "innerKey");
//            Invariant.CheckIsNull(selector, "selector");
//
//            _outerProvider = outerProvider;
//            _outerKey = outerKey;
//            _innerProvider = innerProvider;
//            _innerKey = innerKey;
//            _selector = selector;
//            _cache = new ViewCache<TResult>();
//            _innerCache = new ViewCache<TInner>();
//
//        }
//
//        /// <summary>
//        /// For debugging and tracing only
//        /// </summary>
//        public override IEnumerable<IViewStream> GetProviders()
//        {
//            yield return _outerProvider;
//            yield return _innerProvider;
//        }
//
//        protected override void StreamDataCore()
//        {
//            _innerProvider.StreamData(InnerMsgHandler);
//            _outerProvider.StreamData(OuterMsgHandler);
//        }
//
//        protected override ViewData<TResult> SubscribeCore(StreamMessageDelegate<TResult> callback)
//        {
//            lock(_cache)
//            {
//                _callbacks += callback;
//                return new ViewData<TResult>(_cache.ToList(), _cacheVersion);
//            }
//        }
//
//        protected override void UnsubscribeCore(StreamMessageDelegate<TResult> callback)
//        {
//            lock (_cache)
//            {
//                _callbacks -= callback;
//            }
//        }
//
//        protected override void Dispose(bool disposing)
//        {
//            if(disposing)
//            {
//                _disposed = true;
//                _innerProvider.Unsubscribe(InnerMsgHandler);
//                _innerProvider.Dispose();
//                _outerProvider.Unsubscribe(OuterMsgHandler);
//                _outerProvider.Dispose();
//                lock (_cache)
//                {
//                    _cache.Clear();
//                    _callbacks = null;
//                }
//            }
//        }
//
//        private void InnerMsgHandler(ViewMessageBurst<TInner> msgBurst)
//        {
//            Invariant.CheckIsNull(msgBurst, "msgBurst");
//            if (_disposed) return;
//
//            lock(_cache)
//            {
//                foreach (var msg in _innerCacheSequencer.Resequence(msgBurst))
//                {
//                    ViewMessage<TInner> outMsg;
//                    if(_innerCache.TryProcess(msg, out outMsg))
//                    {
//                        
//                    }
//                }
//            }
//        }
//
//        private void OuterMsgHandler(ViewMessageBurst<TOuter> msgBurst)
//        {
//            Invariant.CheckIsNull(msgBurst, "msgBurst");
//            if (_disposed) return;
//        }
//    }
}